﻿using Abp.Dependency;
using Abp.Threading.BackgroundWorkers;
using Abp.Threading.Timers;
using Abp.Timing;
using Abp.UI;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace ARchGL.Platform.BackgroundWorker
{
    /// <summary>
    /// 清理锁定账户过期缓存
    /// </summary>
    public class CleanLockCacheWorker : PeriodicBackgroundWorkerBase, ISingletonDependency
    {
        private static ConcurrentDictionary<string, ValueTuple<DateTime, int>> LockCache = new ConcurrentDictionary<string, ValueTuple<DateTime, int>>();

        public CleanLockCacheWorker(AbpTimer timer) : base(timer)
        {
            //Timer.Period = 5000;
            Timer.Period = 60000; //1分钟一次轮询
        }

        protected override void DoWork()
        {
            var keys = new List<string>(LockCache.Keys);
            for (int i = 0; i < keys.Count; i++)
            {
                var key = keys[i];
                if (Clock.Now.Subtract(LockCache[key].Item1).TotalMinutes < 5) continue;

                LockCache.TryRemove(key, out var date); //移除过期缓存（缓存5分钟）
            }
        }

        /// <summary>
        /// 检查账户锁定状态
        /// </summary>
        /// <param name="key">用户登录信息加 TenantName</param>
        /// <param name="type">是否更新错误次数，tre 是，false 否</param>
        public static void CheckLockStatus(string key, bool type = false)
        {
            var dict = LockCache.TryGetValue(key, out ValueTuple<DateTime, int> vt);
            if (dict)
            {
                var newVt = new ValueTuple<DateTime, int>(vt.Item1, vt.Item2);
                if (type)
                {
                    ++newVt.Item2;
                    LockCache.TryUpdate(key, newVt, vt);
                }
                if (newVt.Item2 > 5)
                    throw new UserFriendlyException("登录失败", "用户帐户已被锁定。请稍后再试");
            }
            else
            {
                if (type) LockCache.TryAdd(key, new ValueTuple<DateTime, int>(Clock.Now, 1));
            }
        }
    }
}
